LIBRARY IEEE;
   USE IEEE.STD_LOGIC_1164.ALL;
   USE IEEE.STD_LOGIC_ARITH.ALL;
   USE IEEE.STD_LOGIC_UNSIGNED.ALL;
  
   ENTITY fr_align IS
     PORT( din:                  in std_logic_vector(17 downto 0);
           clkin:                in std_logic;
           ld,fal:            out std_logic;
           cn:                out integer range 0 to 255;
           dout:              out std_logic_vector(17 downto 0));                            
         END fr_align;       
   ARCHITECTURE BE OF fr_align IS
      type shift_d is array (0 to 17) of std_logic_vector(7 downto 0);
      constant align:            integer:=2;
      constant loss:             integer:=1;
      constant search:           integer:=3;
      constant fas:    std_logic_vector(7 downto 0):="11011001";
      signal bit_counter:        integer range 0 to 255;
      signal sync_cn:   integer range 0 to 3;
      signal d_reg:     shift_d;
      signal fr_state: integer range 0 to 3;
      signal tem:       std_logic;
    BEGIN 
      cn<=bit_counter;
      dout(0)<=d_reg(0)(0);
      dout(1)<=d_reg(1)(0);
      dout(2)<=d_reg(2)(0);
      dout(3)<=d_reg(3)(0);
      dout(4)<=d_reg(4)(0);
      dout(5)<=d_reg(5)(0);
      dout(6)<=d_reg(6)(0);
      dout(7)<=d_reg(7)(0);
      dout(8)<=d_reg(8)(0);
      dout(9)<=d_reg(9)(0);
      dout(10)<=d_reg(10)(0); 
      dout(11)<=d_reg(11)(0);
      dout(12)<=d_reg(12)(0);
      dout(13)<=d_reg(13)(0);
      dout(14)<=d_reg(14)(0);
      dout(15)<=d_reg(15)(0); 
      dout(16)<=d_reg(16)(0);
      dout(17)<=d_reg(17)(0);  
    process(clkin)
      begin
         if clkin'event and clkin='1'then         
            d_reg(17)(7)<=din(17);
            d_reg(16)(7)<=din(16);
            d_reg(15)(7)<=din(15);
            d_reg(14)(7)<=din(14);
            d_reg(13)(7)<=din(13);
            d_reg(12)(7)<=din(12);
            d_reg(11)(7)<=din(11);
            d_reg(10)(7)<=din(10);
            d_reg(9)(7)<=din(9);
            d_reg(8)(7)<=din(8);
            d_reg(7)(7)<=din(7);
            d_reg(6)(7)<=din(6);
            d_reg(5)(7)<=din(5);
            d_reg(4)(7)<=din(4);
            d_reg(3)(7)<=din(3);
            d_reg(2)(7)<=din(2);
            d_reg(1)(7)<=din(1);
            d_reg(0)(7)<=din(0);          
            for i in 0 to 6 loop
               d_reg(17)(i)<=d_reg(17)(i+1);
               d_reg(16)(i)<=d_reg(16)(i+1);
               d_reg(15)(i)<=d_reg(15)(i+1);
               d_reg(14)(i)<=d_reg(14)(i+1);
               d_reg(13)(i)<=d_reg(13)(i+1);
               d_reg(12)(i)<=d_reg(12)(i+1);
               d_reg(11)(i)<=d_reg(11)(i+1);
               d_reg(10)(i)<=d_reg(10)(i+1);
               d_reg(9)(i)<=d_reg(9)(i+1);
               d_reg(8)(i)<=d_reg(8)(i+1);
               d_reg(7)(i)<=d_reg(7)(i+1);
               d_reg(6)(i)<=d_reg(6)(i+1);
               d_reg(5)(i)<=d_reg(5)(i+1);
               d_reg(4)(i)<=d_reg(4)(i+1);
               d_reg(3)(i)<=d_reg(3)(i+1);
               d_reg(2)(i)<=d_reg(2)(i+1);
               d_reg(1)(i)<=d_reg(1)(i+1);
               d_reg(0)(i)<=d_reg(0)(i+1);
            end loop;
          end if;
      end process;
    process(clkin)
         begin          
         if clkin'event and clkin='1'then
            if bit_counter=254 then
               ld<='0';
            else
               ld<='1';
            end if;
            case fr_state is
                 when loss=>
                     fal<='1';
                     if d_reg(16)(7 downto 0)=fas then
                        fr_state<=search;
                        bit_counter<=1;
                        sync_cn<=0;
                       -- fal<='1';
                     else
                        bit_counter<=254;
                     end if;                 
                 when search=>
                      fal<='1';
                      if bit_counter=0 then
                        if d_reg(16)(7 downto 0)/=fas then
                           fr_state<=loss;
                           bit_counter<=254;
                        else 
                           sync_cn<=sync_cn+1; bit_counter<=bit_counter+1;
                           if sync_cn=3 then
                              fr_state<=align;                              
                              sync_cn<=0;
                           end if;
                        end if;
                      else
                        bit_counter<=bit_counter+1;                        
                     end if;
                 when align=>
                     fal<='0';
                     if bit_counter=0 then
                        if d_reg(16)(7 downto 0)/=fas then
                           sync_cn<=sync_cn+1;
                           if sync_cn=3 then
                              fr_state<=loss;
                           end if;
                        else
                           sync_cn<=0;
                        end if;
                           bit_counter<=bit_counter+1;
                     else
                        bit_counter<=bit_counter+1;                        
                     end if;
                 when others=>
                     fal<='1';
                     fr_state<=loss;
                     bit_counter<=254;
                end case;             
            end if;          
          end process;           
            
   end be;